package com.neusoft.license.api.license;

import com.neusoft.license.api.holder.LicenseManagerHolder;
import com.neusoft.license.api.param.LicenseVerifyParam;
import com.neusoft.license.api.cache.CacheLicenseContextHolder;
import com.neusoft.license.common.constant.CommonConstant;
import com.neusoft.license.common.constant.RestConstant;
import com.neusoft.license.common.exception.LicenseException;
import com.neusoft.license.common.param.CustomKeyStoreParam;
import de.schlichtherle.license.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.FileCopyUtils;

import java.io.File;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.prefs.Preferences;

/**
 * @Author: xlh
 * @Description: License校验类
 * @Date: Create in 17:06 2020/9/17 0017
 */
@Slf4j
public class LicenseVerify {

    private static String LICENSE_PATH;

    private static String PUBLIC_KEY_STORE_PATH;

    private static final String PREFIX = "license";

    private static final String SUFFIX = ".lic";

    {
        ClassPathResource resource = new ClassPathResource(CommonConstant.LICENSE_FILE);
        LICENSE_PATH = resource.getPath();
        resource = new ClassPathResource(CommonConstant.PUBLIC_KEY_STORE_FILE);
        PUBLIC_KEY_STORE_PATH = resource.getPath();
    }

    /**
     * 安装License证书
     * @param param
     * @return
     */
    public synchronized LicenseContent install(LicenseVerifyParam param){
        if (null == LICENSE_PATH || "" == LICENSE_PATH) {
            throw new LicenseException(RestConstant.ERROR_CODE, RestConstant.NOT_FOUND_LICENSE);
        }

        if (null == PUBLIC_KEY_STORE_PATH || "" == PUBLIC_KEY_STORE_PATH) {
            throw new LicenseException(RestConstant.ERROR_CODE, RestConstant.NOT_FOUND_PUBLIC_KEY_STORE);
        }

        param.setLicensePath(LICENSE_PATH);
        param.setPublicKeysStorePath(PUBLIC_KEY_STORE_PATH);
        LicenseContent result;
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 安装License
        try{
            LicenseManager licenseManager = LicenseManagerHolder.getInstance(initLicenseParam(param));
            licenseManager.uninstall();
            ClassPathResource resource = new ClassPathResource(param.getLicensePath());
            InputStream inputStream = resource.getInputStream();
            File license = File.createTempFile(PREFIX, SUFFIX);
            byte[] bytes = FileCopyUtils.copyToByteArray(inputStream);
            FileCopyUtils.copy(bytes, license);
            result = licenseManager.install(license);
            log.info(MessageFormat.format(RestConstant.INSTALL_LICENSE_EFFECTIVE,
                    format.format(result.getNotBefore()),format.format(result.getNotAfter())));
            CacheLicenseContextHolder.setLicense(result.getNotAfter());
        }catch (Exception e){
            log.error(RestConstant.LICENSE_FAILURE,e);
            throw new LicenseException(RestConstant.ERROR_CODE, e.getMessage());
        }
        return result;
    }

    /**
     * 校验License证书
     * @return
     */
    public boolean verify(){
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date expiryTime = CacheLicenseContextHolder.getLicense();
        log.info(MessageFormat.format(RestConstant.LICENSE_EXPIRY_TIME, format.format(expiryTime)));
        boolean result = expiryTime.after(new Date());
        if (!result) {
            throw new LicenseException(RestConstant.ERROR_CODE, RestConstant.LICENSE_INVALID);
        }
        return true;
    }
    /*@Deprecated
    public boolean verify(){
        LicenseManager licenseManager = LicenseManagerHolder.getInstance(null);
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 校验License
        try {
            LicenseContent licenseContent = licenseManager.verify();
            log.info(MessageFormat.format(RestConstant.LICENSE_EFFECTIVE,
                    format.format(licenseContent.getNotBefore()),format.format(licenseContent.getNotAfter())));
        }catch (Exception e){
            log.error(RestConstant.LICENSE_NOT_FOUND,e);
            throw new LicenseException(RestConstant.ERROR_CODE, e.getMessage());
        }
        Date expiryTime = CacheLicenseContextHolder.getLicense();
        log.info(RestConstant.LICENSE_EXPIRY_TIME, expiryTime);
        return expiryTime.after(new Date());
    }*/



    /**
     * 初始化证书生成参数
     * @param param
     * @return
     */
    private LicenseParam initLicenseParam(LicenseVerifyParam param){
        Preferences preferences = Preferences.userNodeForPackage(LicenseVerify.class);

        CipherParam cipherParam = new DefaultCipherParam(param.getStorePass());

        KeyStoreParam publicStoreParam = new CustomKeyStoreParam(LicenseVerify.class
                ,param.getPublicKeysStorePath()
                ,param.getPublicAlias()
                ,param.getStorePass()
                ,null);
        return new DefaultLicenseParam(param.getSubject()
                ,preferences
                ,publicStoreParam
                ,cipherParam);
    }

}
